From ecc861bf06e7e3f3f92c9b9f1ae7127a82bad2c8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jonas=20=C3=85dahl?= Date: Tue, 24 Nov 2020 22:02:53 +0100 Subject: [PATCH] Pass the layout signal via GdkSurface to GtkRoot Don't have GtkRoot listen directly to the layout signal on the frame clock, but let it pass through GdkSurface. This will allow GdkSurface to be more involved in the layout phase. --- gdk/gdksurface.c | 46 ++++++++++++++++++++++++++++++++++++++++++ gdk/gdksurface.h | 3 +++ gtk/gtkroot.c | 21 ++++++++++++------- gtk/gtkwidget.c | 2 +- gtk/gtkwidgetprivate.h | 2 ++ 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c index f5f4a5790d..226a7c7e53 100644 --- a/gdk/gdksurface.c +++ b/gdk/gdksurface.c @@ -1370,6 +1370,45 @@ gdk_surface_process_updates_internal (GdkSurface *surface) g_object_unref (surface); } +static void +gdk_surface_layout_on_clock (GdkFrameClock *clock, + void *data) +{ + GdkSurface *surface = GDK_SURFACE (data); + + g_return_if_fail (GDK_IS_SURFACE (surface)); + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + if (!GDK_SURFACE_IS_MAPPED (surface)) + return; + + if (surface->update_freeze_count) + return; + + g_signal_emit (surface, signals[LAYOUT], 0, surface->width, surface->height); +} + +void +gdk_surface_request_layout (GdkSurface *surface) +{ + GdkFrameClock *frame_clock; + + if (surface->update_freeze_count || + gdk_surface_is_toplevel_frozen (surface)) + { + surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_LAYOUT; + return; + } + + frame_clock = gdk_surface_get_frame_clock (surface); + g_return_if_fail (frame_clock); + + gdk_frame_clock_request_phase (frame_clock, + GDK_FRAME_CLOCK_PHASE_LAYOUT); +} + static void gdk_surface_paint_on_clock (GdkFrameClock *clock, void *data) @@ -2451,6 +2490,10 @@ gdk_surface_set_frame_clock (GdkSurface *surface, "resume-events", G_CALLBACK (gdk_surface_resume_events), surface); + g_signal_connect (G_OBJECT (clock), + "layout", + G_CALLBACK (gdk_surface_layout_on_clock), + surface); g_signal_connect (G_OBJECT (clock), "paint", G_CALLBACK (gdk_surface_paint_on_clock), @@ -2471,6 +2514,9 @@ gdk_surface_set_frame_clock (GdkSurface *surface, g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock), G_CALLBACK (gdk_surface_resume_events), surface); + g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock), + G_CALLBACK (gdk_surface_layout_on_clock), + surface); g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock), G_CALLBACK (gdk_surface_paint_on_clock), surface); diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h index 6b2cfcd03b..4c47fe659b 100644 --- a/gdk/gdksurface.h +++ b/gdk/gdksurface.h @@ -118,6 +118,9 @@ void gdk_surface_beep (GdkSurface *surface); GDK_AVAILABLE_IN_ALL void gdk_surface_queue_render (GdkSurface *surface); +GDK_AVAILABLE_IN_ALL +void gdk_surface_request_layout (GdkSurface *surface); + GDK_AVAILABLE_IN_ALL GdkFrameClock* gdk_surface_get_frame_clock (GdkSurface *surface); diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c index a480173695..6bdf1b74a1 100644 --- a/gtk/gtkroot.c +++ b/gtk/gtkroot.c @@ -195,8 +195,10 @@ gtk_root_after_update_cb (GdkFrameClock *clock, } static void -gtk_root_layout_cb (GdkFrameClock *clock, - GtkRoot *self) +gtk_root_layout_cb (GdkSurface *surface, + int width, + int height, + GtkRoot *self) { GtkWidget *widget = GTK_WIDGET (self); @@ -231,19 +233,22 @@ gtk_root_layout_cb (GdkFrameClock *clock, if (gtk_root_needs_layout (self)) { - gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE); - gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT); + gdk_frame_clock_request_phase (gdk_surface_get_frame_clock (surface), + GDK_FRAME_CLOCK_PHASE_UPDATE); + gdk_surface_request_layout (surface); } } void gtk_root_start_layout (GtkRoot *self) { + GdkSurface *surface; GdkFrameClock *clock; if (!gtk_root_needs_layout (self)) return; + surface = gtk_widget_get_surface (GTK_WIDGET (self)); clock = gtk_widget_get_frame_clock (GTK_WIDGET (self)); if (clock == NULL) return; @@ -260,19 +265,20 @@ gtk_root_start_layout (GtkRoot *self) GINT_TO_POINTER (after_update_handler)); layout_handler = - g_signal_connect (clock, "layout", + g_signal_connect (surface, "layout", G_CALLBACK (gtk_root_layout_cb), self); g_object_set_qdata (G_OBJECT (self), quark_layout_handler, GINT_TO_POINTER (layout_handler)); } gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE); - gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT); + gdk_surface_request_layout (surface); } void gtk_root_stop_layout (GtkRoot *self) { + GdkSurface *surface; GdkFrameClock *clock; guint layout_handler; guint after_update_handler; @@ -287,8 +293,9 @@ gtk_root_stop_layout (GtkRoot *self) if (layout_handler == 0) return; + surface = gtk_widget_get_surface (GTK_WIDGET (self)); clock = gtk_widget_get_frame_clock (GTK_WIDGET (self)); - g_signal_handler_disconnect (clock, layout_handler); + g_signal_handler_disconnect (surface, layout_handler); g_signal_handler_disconnect (clock, after_update_handler); g_object_set_qdata (G_OBJECT (self), quark_layout_handler, NULL); g_object_set_qdata (G_OBJECT (self), quark_after_update_handler, NULL); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index ab9de00cd2..6d1e3c865d 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -3244,7 +3244,7 @@ gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget, } } -static GdkSurface * +GdkSurface * gtk_widget_get_surface (GtkWidget *widget) { GtkNative *native = gtk_widget_get_native (widget); diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index a79ee938da..667df882ce 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -228,6 +228,8 @@ void gtk_widget_ensure_resize (GtkWidget *widget); void gtk_widget_ensure_allocate (GtkWidget *widget); void _gtk_widget_scale_changed (GtkWidget *widget); +GdkSurface * gtk_widget_get_surface (GtkWidget *widget); + void gtk_widget_render (GtkWidget *widget, GdkSurface *surface, const cairo_region_t *region); -- 2.30.2